<template>
  <div class="in-btns">
    <el-button
      type="primary"
      size="mini"
      @click="inCrement"
    >
      count is {{ count }}
    </el-button>
  </div>
  <!--引入全局自定义变量 -->
  <div class="custom-var">
    {{ $custom_var }}
  </div>
  <!--自定义指令 -->
  <div
    class="directive-box"
    mt-20
  >
    自定义指定 <el-button
      v-preventClick
      type="primary"
      size="mini"
      @click="loginClick('service')"
    >
      登录
    </el-button>
  </div>
  <!--模板引用，使用ref渲染 -->
  <div
    ref="render_ref"
    mt-20
  >
    This is a root element
  </div>
  <!--组合式 API 模板引用在 v-for 内部使用时没有特殊处理。相反，请使用函数引用执行自定义处理： -->
  <div mt-20>
    组合式 API 模板引用在 v-for 内部使用时没有特殊处理
    <div
      v-for="(item, i) in divsList"
      :ref="el => { if (el) divs[i] = el }"
      :key="i"
    >
      {{ item }}
    </div>
  </div>

  <!--动态表格校验 -->
  <dymic-form />
  <!--动态表格 -->
  <dymic-table />
  <!--动态登录表格 -->
  <dymic-login />
  <!--二次封装组件 -->
  <dymic-date-picker
    v-model="datePicker"
    type="datetimerange"
    value-format="YYYY-MM-DD HH:mm:ss"
  />

  <div class="count-btns">
    <el-input
      v-model="num1"
      v-focus
      placeholder="请输入值"
      style="width: 150px;"
      clearable
    /> +
    <el-input
      v-model="num2"
      v-focus
      placeholder="请输入值"
      style="width: 150px;"
      clearable
    /> = {{ total }}
  </div>
  <div class="user-btns">
    <ul
      v-for="ele in user"
      :key="ele.id"
      mt-10
    >
      <li>{{ ele.name }}</li>
    </ul>
    <el-button
      v-preventClick
      type="primary"
      size="mini"
      @click="addUser"
    >
      添加用户信息
    </el-button>
  </div>
  <p class="txt cursor">
    to-do-list
  </p>
  <!--input输入list内容 -->
  <div class="do-list">
    <el-input
      v-model="taskName"
      v-focus
      class="input"
      placeholder="请输入任务"
      clearable
      @keyup.enter="addTask"
    />
  </div>  
  <!--todolist内容展示和删除 -->
  <ul class="ul">
    <li
      v-for="(item,idx) in taskList"
      :key="idx"
      class="items"
    >
      <div
        :class="['item-name',item.isfinished ? 'active' : '']"
        @click="updateStatus(idx,!item.isfinished)"
      >
        {{ item.name }}
      </div>
      <div
        class="item-delete"
        @click="deleteTask(idx)"
      >
        删除
      </div>
    </li>
  </ul>
  <!--引入组件 -->
  <Menu :menu="menu" />

  <!--子组件的引入 v-model:value等同于props:'value'和emits('update:value')-->
  <!-- <child-component v-model:value="myValue" /> -->
</template>
// 由于 setup 被提升到 script 标签上了，自然也就没办法接收 props 和 context 这两个参数
<script lang="ts">
import { 
  defineComponent, ref, toRefs,reactive,computed,watchEffect,
  getCurrentInstance,onUpdated,onMounted,onBeforeUpdate
  // onUnmounted,onBeforeUpdate,onUpdated,onActivated,onDeactivated
} from "vue"
import { useRouter,useRoute } from "vue-router"
import { useStore } from "vuex"
import { login } from "/@/api/api"
import Menu from "/@/views/demo/Menu.vue"
import DymicForm from "/@/views/demo/dymic-form.vue"
import DymicTable from "/@/views/demo/dymic-table.vue"
import DymicLogin from "/@/views/demo/dymic-form-login.vue"
import DymicDatePicker from "/@/views/demo/dymic-date-picker.vue"
export default defineComponent({
  name:"Home",
  components:{
    Menu,
    DymicForm,
    DymicTable,
    DymicLogin,
    DymicDatePicker
  },
  props:{
    isShow:{
      type:Boolean,
      default:false
    }
  },
  emits:["update:show","otherEmit"], 
  setup(props,{ attrs,emit },context:SetupContext) {
    const store = useStore() // 相当于 vue2 中的 this.$store,此写法适合index.ts中
    const taskName = ref("") // 通过ref包装的值，取值或设置值的时候，需要通过.value来进行设置 ref来获取组件的引用，替代this.$refs写法
    // reactive对复杂数据进行响应式处理，它的返回值是一个proxy对象，在setup函数中返回时，可以用toRefs对proxy对象进行结构
    const userList = reactive({
      user:[]
    })
    const num1 = ref(null)
    const num2 = ref(null)
    const total = computed(() => Number(num1.value) + Number(num2.value)) 

    // 获取组件实例，用于高级用法或库的开发
    // const internalInstance = getCurrentInstance()

    // 获取自定义全局变量
    const custom_var = getCurrentInstance()?.appContext.config.globalProperties.$custom_var
    console.log(custom_var,"--custom_var--")

    const divs = ref([])
    const divsList = reactive([1,2,3])
    // 确保在每次更新之前重置ref
    onBeforeUpdate(() => {
      divs.value = []
    })

    // 渲染ref自定义模板,并通过 ref="render_ref"，将其绑定到 div 作为其 ref,模板引用只会在初始渲染之后获得赋值
    const render_ref = ref(null)
    onMounted(() => {
      console.log(render_ref.value,"渲染ref属性定义模板")
    })

    // 使用emit事件
    emit("update:show")
    emit("otherEmit")

    // 跟踪使用attrs和slots ，attrs 和 slots 是有状态的对象，它们总是会随组件本身的更新而更新
    // 并始终以 attrs.x 或 slots.x 的方式引用 property。请注意，与 props 不同，attrs 和 slots 是非响应式的。如果你打算根据 attrs 或 slots 更改应用副作用，那么应该在 onUpdated 生命周期钩子中执行此操作
    const _handleAttrsChange = () => {
      console.log(attrs,"===attrs===")
    }
    onUpdated(() => {
      _handleAttrsChange()
    })

    const loginClick = (name) => {
      let input = "SERVICE=http://172.16.4.78:5557/demo/caslogin.jsp?service=gghhjjkk"
      input = input.toLowerCase()
      let startLen = name.length + 1
      const url = input.substring(input.indexOf(name) + startLen , input.length)
      console.log(url)
      console.log("登录中")
    }

    // 自定义日期
    const datePicker = ref("")

    // 菜单
    const menu = reactive([{
      id:"1",
      label:"处理中心",
      children:[]
    },{
      id:"2",
      label:"我的工作台",
      children:[]
    },{
      id:"3",
      label:"消息中心",
      children:[]
    },{
      id:"4",
      label:"订单管理",
      children:[]
    }]
    )

    // 使用props和emit方法
    const close = () => context.emits("update:show",!props.isShow)

    const taskList = computed(() => store.state.taskList)
    const count = computed(() => store.state.todoState.count)
    // 第二种方法
    const computedData = {
      // 计算属性写法 别忘记引入 computed
      newNum : computed(() => {
        return state.count * 2
      })
    }

    // watch(taskList,(curVal,oldVal) => {
    //   console.log("监听器",curVal,oldVal)
    // },
    // { deep:true }
    // )

    // watchEffect响应式跟踪函数中引用的响应式数据，当响应式数据改变时，会重新执行函数
    const stop = watchEffect(() => console.log(`触发count值的变化：${count.value}`))

    const route = useRoute() // 相当于 vue2 中的 this.$route   
    const router = useRouter() // 相当于 vue2 中的 this.$router
    console.log("用于获取当前路由数据",route)
    console.log("用于路由跳转：",router)

    const addUser = () => {
      let len = userList.user.length
      userList.user.push({
        id:len,
        name:`张三_${len}`
      })
    }
    
    const inCrement = () => store.commit("todoState/increment",count.value)

    const addTask = () => {
      store.commit("createTask",{
        name:taskName.value,
        isfinished:false
      })
      taskName.value = ""
    }

    const deleteTask = (idx) => {
      store.commit("deleteTask",idx)
    }

    const updateStatus = (idx,status) => {
      store.commit("updateTask",{
        idx,
        status
      })
    }

    const countNum = ref(0)
    const state = reactive({
      year: 2021
    })
    watchEffect(() => {
      console.log(countNum.value,"---watchEffect---")
      console.log(state.year,"---watchEffect---")
    })

    // setInterval(() => {
    //   countNum.value++
    //   state.year++
    // }, 1000)

    return {
      render_ref,
      taskName,
      num1,
      num2,
      total,
      menu,
      taskList,
      divs,
      divsList,
      count,
      inCrement,
      ...toRefs(userList),
      computedData,
      close,
      stop,
      addUser,
      addTask,
      deleteTask,
      updateStatus,
      loginClick,
      datePicker
    } 
  },
  mounted() {
    this.onSubmit({
      username:"admin",
      password:"123456"
    })
  },
  // setup是围绕 beforeCreate和create生命周期钩子运行，所以不需要显式定义它们
  methods:{
    async onSubmit(params):Promise<void> {
      const res = await login(params)
      console.log(res)
    }  
  }
  
})

</script>
  
<style lang="less" scoped>
.txt {
  color: @primay-color;
}

.in-btns,
.user-btns,
.count-btns {
  margin: 15px 0;
}

.do-list {
  max-width: 400px;
  margin: 0 auto;

  .input {
    width: 100%;
    height: 40px;
    border-radius: 5px;
    outline-style: none;
    border: 2px solid #999;
    padding: 5px 10px;
  }
}

.items {
  height: 40px;
  line-height: 40px;
  padding-bottom: 5px;
  border-bottom: 1px solid #dcdfe6;
  color: #333;

  .item-name {
    float: left;
    height: 40px;
    line-height: 40px;
    cursor: pointer;
  }

  div.active {
    text-decoration: line-through;
    color: #999;
  }

  .item-delete {
    float: right;
    color: #409eff;
    margin-right: 5px;
    text-align: center;
    cursor: pointer;
  }
}

</style>